use std::sync::Arc;
use chrono::Local;
use prisma_client_rust::{QueryError};
use serde::{Serialize, Deserialize};
use rspc::{Type};
use uuid::Uuid;
use crate::prisma::{PrismaClient, config};

#[derive(Clone, Serialize, Deserialize, Type, Debug)]
pub struct ConfigArg {
    pub key: String,
}

#[derive(Clone, Serialize, Deserialize, Type, Debug)]
pub struct SaveConfigData {
    pub key: String,
    pub value: String,
}

pub struct ConfigManager {

}

impl ConfigManager {
    pub async fn all(client: Arc<PrismaClient>) -> Result<Vec<config::Data>, QueryError> {
        Ok(
            client
                .config()
                .find_many(vec![])
                .exec()
                .await?
        )
    }

    pub async fn get(client: Arc<PrismaClient>, args: ConfigArg) -> Result<Option<config::Data>, QueryError> {
        Ok(
            client
                .config()
                .find_first(vec![
                    config::key::equals(args.key.to_string())
                ])
                .exec()
                .await?
        )
    }

    pub async fn save(client: Arc<PrismaClient>, args: SaveConfigData) -> Result<(), QueryError> {
        let _ = client
            .config()
            .upsert(
                config::key::equals(args.key.to_string()),
                (
                    Uuid::new_v4().clone().to_string(),
                    args.key.to_string(),
                    args.value.to_string(),
                    vec![]
                ),
                vec![
                    config::key::set(args.key.to_string()),
                    config::value::set(args.value.to_string()),
                    config::updated_at::set(Some(Local::now().into()))
                ]
            )
            .exec()
            .await?;

        Ok(())
    }
}
